# @Time : 2024-10-25 11:38
# @Author : Fioman 
# @Phone : 13149920693
"""
字典dict本身是C语言实现的,性能比较高,以下是python实现的一些它的子类,性能不高,但是功能比较特殊
1) collections.OrderedDict: 插入键值对的时候保留了顺序
2) collections.defaultdict: 提供了一个默认值工厂函数来处理不存在的键,如果键不存在就调用这个工厂函数获取
# 并且将这个默认是赋值给这个键
3) collections.UserDict: 一个包装类,用户自定义字典的时候可以继承它
"""
# region 1. OrderDict的使用
from collections import OrderedDict, UserDict

orderDict = OrderedDict({"a": 1})
orderDict["b"] = 2
orderDict["c"] = 3
orderDict["d"] = 4
orderDict["e"] = 0
print(orderDict)
# 假如我想要将a和e的位置互换呢
orderDict.move_to_end("a", last=True)  # 将a移动到末尾
orderDict.move_to_end("e", last=False)  # 将e移动到开头
print(orderDict)  # 还可以手动的调整它们的顺序
# endregion

# region 2. defaultdict
from collections import defaultdict


def func():
    return 100


defaultDict = defaultdict(func)
print(defaultDict["a"])  # 相当于是 defaultDict["a] = func()
print(defaultDict)  # 这里已经有"a":100这个键值对了
defaultDict = defaultdict(list)
defaultDict["a"].append(1)
print(defaultDict)
defaultDict = defaultdict(lambda: 10)
print(defaultDict["b"])
print(defaultDict)


# endregion

# region 3. UserDict的用法
# 为什么不能直接继承dict
class Mydict(dict):
    def __getitem__(self, item):
        return super().__getitem__(item)

    def __setitem__(self, key, value):
        super().__setitem__(key, value * 2)


mydict = Mydict(a=10)
print("myDict: {}".format(mydict))  # 这里并没有调用__set_item__方法打印的结果{'a':10}
mydict = Mydict()
mydict["a"] = 10  # 这就打印的是{'a':20}
print("myDict: {}".format(mydict))


# 所以我们一般不继承dict的原因就是因为dict是C语言实现的,它内部的一些特殊的方法我们无法拦截,
# 存在一些潜在的兼容性问题.

class RightDict(UserDict):
    def __setitem__(self, key, value):
        super().__setitem__(key, value * 100)


mydict = RightDict(a=10)  # myDict: {'a': 1000}
print("myDict: {}".format(mydict))
mydict = RightDict()
mydict["a"] = 10
print("myDict: {}".format(mydict))  # {'a': 1000}


# endregion

# region 4. 自定义字典key大小写不敏感
class IgnoreCaseDict(UserDict):
    def __setitem__(self, key: str, value):
        super().__setitem__(key.lower().strip(), value)

    def __getitem__(self, key: str):
        return super().__getitem__(key.lower().strip())

    def __delitem__(self, key: str):
        return super().__delitem__(key.lower().strip())

    def get(self, key: str, default=None):
        return super().get(key.lower().strip(), default)

    def __contains__(self, key: str):
        return super().__contains__(key.lower().strip())

    def update(self, otherDict):
        for key, value in otherDict.items():
            self[key] = value
        # endregion


mydict = IgnoreCaseDict()
mydict["hello"] = "小写"
print("myDict: {}".format(mydict))
print(mydict["hello".upper()])  # 用大写的方式访问得到的结果也是一致的
mydict.update({"FioMAN": "大小写混合"})  # 里面保存和访问的时候全部转换为小写
print("myDict: {}".format(mydict))
